package com.haier.npt.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisDao {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	/**
	 * 查询key的过期时间
	 *
	 * @param key
	 * @return
	 */
	public long ttl(String key) {
		if (stringRedisTemplate.hasKey(key)) {
			return stringRedisTemplate.getExpire(key);
		}
		return 0;
	}

	/**
	 * 是否有key值
	 *
	 * @param key
	 * @return
	 */
	public boolean hasKey(String key) {
		if (key != null) {
			return this.stringRedisTemplate.hasKey(key);
		}
		return false;
	}

	/**
	 * 根据key的前缀列出所有的key值
	 *
	 * @param keyPrefix
	 * @return
	 */
	public Set<String> keys(String keyPrefix) {
		return this.stringRedisTemplate.keys(keyPrefix);
	}

	/**
	 * 字符串类型:通过key值获取对应的value对象
	 *
	 * @param key
	 * @return
	 */
	public String get(final String key) {
		if (hasKey(key)) {
			return stringRedisTemplate.opsForValue().get(key);
		}
		return null;
	}

	/**
	 * 字符串类型:存入key-value对象，如果key存在，那么默认更新value
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(final String key, final String value) {

		if (key != null && value != null) {
			this.stringRedisTemplate.opsForValue().set(key, value);
			return true;
		}
		return false;
	}

	/**
	 * 字符串类型:存入key-value对象，如果key存在，那么默认更新value
	 *
	 * @param key
	 * @param value
	 * @param timeout 超时时间
	 * @param unit    过期时间单位
	 * @return
	 */
	public boolean set(final String key, final String value, long timeout, TimeUnit unit) {
		if (key != null && value != null) {
			this.stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
			return true;
		}
		return false;
	}

	/**
	 * 字符串类型:通过key删除对应的key和value
	 *
	 * @param key
	 * @return
	 */
	public void delete(final String key) {
		if (hasKey(key)) {
			this.stringRedisTemplate.delete(key);
		}
	}

	/**
	 * 字符串类型:通过key模糊删除对应的key和value
	 *
	 * @param key
	 * @return
	 */
	public void vagueDelete(final String key) {
		this.stringRedisTemplate.delete(stringRedisTemplate.keys(key + "*"));
	}

	/**
	 * 字符串类型:设置key对应的超时时间
	 *
	 * @param key
	 * @param
	 * @return
	 */
	public boolean expire(final String key, final Long timeout, TimeUnit unit) {
		if (hasKey(key)) {
			BoundValueOperations<String, String> ops = this.stringRedisTemplate.boundValueOps(key);
			return ops.expire(timeout, unit);
		}
		return false;
	}

	/**
	 * 字符串类型:根据key设置value值,如果key中的value存在,那么返回false
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean setnx(final String key, final String value) {
		BoundValueOperations<String, String> ops = this.stringRedisTemplate.boundValueOps(key);
		return ops.setIfAbsent(value);
	}

	public boolean setnx(final String key, final String value, long timeout, TimeUnit timeUnit) {
		BoundValueOperations<String, String> ops = this.stringRedisTemplate.boundValueOps(key);
		boolean result = ops.setIfAbsent(value);
		ops.expire(timeout, timeUnit);
		return result;
	}

	/**
	 * hash类型:
	 * 设置 key 指定的哈希集中指定字段的值
	 * 如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key 关联
	 * 如果字段在哈希集中存在，它将被重写
	 *
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public void hset(final String key, final String field, final String value) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		ops.put(field, value);
	}

	/**
	 * hash类型: 带超时
	 * 设置 key 指定的哈希集中指定字段的值
	 * 如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key 关联
	 * 如果字段在哈希集中存在，它将被重写
	 *
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public void hset(final String key, final String field, final String value, long timeout, TimeUnit unit) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		ops.put(field, value);
		ops.expire(timeout, unit);
	}

	/**
	 * hash类型:返回 key 指定的哈希集中该字段所关联的值
	 *
	 * @param key
	 * @param field
	 * @return
	 */
	public String hget(final String key, final String field) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		if (ops.hasKey(field)) {
			return ops.get(field);
		}
		return null;
	}

	/**
	 * hash类型:返回 key 指定的哈希集中所有字段的名字
	 *
	 * @param key
	 * @return
	 */
	public Set<String> hkeys(final String key) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		return ops.keys();

	}

	/**
	 * hash类型:从 key 指定的哈希集中移除指定的域。
	 *
	 * @param key
	 * @param fields
	 * @return
	 */
	public Long hdel(final String key, final Object... fields) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		return ops.delete(fields);
	}

	/**
	 * hash类型: 删除指定域的所有字段
	 *
	 * @param key
	 * @return
	 */
	public Long hdelAll(final String key) {
		try {
			Set<String> keys = hkeys(key);
			if (keys != null && keys.size() > 0) {
				for (String item : keys) {
					return hdel(key, item);
				}
			}
		} catch (Exception e) {

		}
		return 0L;
	}

	/**
	 * hash类型:返回 key 指定的哈希集包含的字段的数量
	 *
	 * @param key
	 * @return
	 */
	public Long hlen(final String key) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		return ops.size();
	}

	/**
	 * hash类型:返回hash里面key是否存在的标志
	 *
	 * @param key
	 * @param field
	 * @return
	 */
	public Boolean hexists(final String key, final String field) {
		BoundHashOperations<String, String, String> ops = this.stringRedisTemplate.boundHashOps(key);
		return ops.hasKey(field);
	}

	/**
	 * 获取某前缀的key数量
	 * @return
	 */
	public int getOnlineCount(String prefix) {
		return stringRedisTemplate.keys(prefix + "*").size();
	}
}